package com.weiguan.xmpp.api;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.weiguan.xmpp.util.StringUtils;

/**
 * 
 * xmpp RestAPi服务
 * 
 */
public class XmppRestApi {

	public static class XmppUser {
		public long userId;
		public int isVip;
		public String userAlias;
		public String nickName;

		public static XmppUser newXmppUser(String nickName) {
			String[] str = nickName.split(":");
			if (str.length < 2) {
				return null;
			}
			try {
				long userId = Long.parseLong(str[0]);
				String userAlias = str[1];
				int isVip = 0;
				if (str.length == 3) {
					isVip = Integer.parseInt(str[2]);
				}
				XmppUser user = new XmppUser();
				user.userAlias = userAlias;
				user.userId = userId;
				user.isVip = isVip;
				user.nickName = nickName;
				return user;
			} catch (Exception e) {
				return null;
			}
		}

		private XmppUser() {
		}

		public String toString() {
			return userId + ":" + userAlias + ":" + isVip;
		}
	}

	private XmppRestApi() {
	}

	private static String seriviceName;// 地址
	private static String host;// 地址
	private static String secret;// key

	/**
	 * 初始化
	 * 
	 * @param host
	 * @param serviceName
	 * @param secret
	 */
	public static void init(String host, String serviceName, String secret) {
		XmppRestApi.host = host;
		XmppRestApi.seriviceName = serviceName;
		XmppRestApi.secret = secret;
	}

	/**
	 * 获取房间在线人数
	 * 
	 * @param roomName
	 * @return
	 */
	public static int getRoomUserCount(String roomName) {
		try {
			String getURL = "http://%s:9090/plugins/restapi/v1/chatrooms/%s/participants";

			getURL = String.format(getURL, host, roomName);

			String result = httpGo(getURL, "GET", null);

			if (StringUtils.isBlank(result)) {
				return 0;
			}
			try {
				JSONObject obj = JSONObject.parseObject(result);
				if (obj.isEmpty()) {
					return 0;
				}
				return obj.getJSONArray("participant").size();
			} catch (Exception e) {
			}
			return 1;
			// String resultCount = XPathHelper.getNodeValue(result,
			// "count(/participants/participant)");
			// return StringUtils.parseInt(resultCount, 0);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return 0;
	}

	/**
	 * 获取房间用户
	 * 
	 * @param roomName
	 * @return
	 */
	public static List<XmppUser> getRoomUsers(String roomName) {
		try {
			String getURL = "http://%s:9090/plugins/restapi/v1/chatrooms/%s/participants";

			getURL = String.format(getURL, host, roomName);

			String result = httpGo(getURL, "GET", null);
			if (StringUtils.isBlank(result)) {
				return null;
			}

			List<XmppUser> users = new ArrayList<XmppUser>();

			JSONObject obj = JSONObject.parseObject(result);

			if (obj.isEmpty()) {
				return null;
			}
			try {
				JSONObject res = obj.getJSONObject("participant");
				// 尝试取一个,有可能就一个
				String testNickName = res.getString("jid");
				// 不为空就取到了
				if (!StringUtils.isBlank(testNickName)) {
					if (!testNickName.contains("@")) {
						return null;
					}
					testNickName = testNickName.substring(testNickName.lastIndexOf("/") + 1, testNickName.length());
					XmppUser user = XmppUser.newXmppUser(testNickName);
					if (user == null) {
						return null;
					}
					users.add(user);
					return users;
				}
				return null;
			} catch (Exception e) {
			}

			JSONArray array = obj.getJSONArray("participant");
			for (int i = 0; i < array.size(); i++) {
				JSONObject v = array.getJSONObject(i);

				String nickName = v.getString("jid");
				if (!nickName.contains("@")) {
					continue;
				}
				nickName = nickName.substring(nickName.lastIndexOf("/") + 1, nickName.length());
				XmppUser user = XmppUser.newXmppUser(nickName);
				if (user == null) {
					continue;
				}
				users.add(user);
			}
			return users;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 把人踢出房间并且加入黑名单
	 * 
	 * @param roomName
	 * @param kilcRole
	 */
	public static void kickAndLockRole(String roomName, String userName) {
		lockUser(userName);
		addUserToRoom(userName, roomName, XmppUserType.outcasts.toString());
		unLockUser(userName);
	}

	/**
	 * 给房间加入一个用户
	 * 
	 * @param userName
	 * @param roomName
	 * @param userType
	 * @return 201 成功
	 */
	public static boolean addUserToRoom(String userName, String roomName, String userType) {
		try {
			String postURL = "http://%s:9090/plugins/restapi/v1/chatrooms/%s/%s/%s";

			postURL = String.format(postURL, host, roomName, userType, userName);

			int status = httpGoReturnStatus(postURL, "POST", null);
			if (status == 201) {
				System.out.println("把用户添加到房间成功,userName=" + userName + ",member=" + userType);
			}
			return status == 201;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * 把用户从房间删除
	 * 
	 * @param userName
	 * @param roomName
	 * @param userType
	 * @return 200 成功
	 */
	public static boolean deleteUserFromRoom(String userName, String roomName, String userType) {
		try {
			String deleteURL = "http://%s:9090/plugins/restapi/v1/chatrooms/%s/%s/%s";

			deleteURL = String.format(deleteURL, host, roomName, userType, userName);

			int status = httpGoReturnStatus(deleteURL, "DELETE", null);
			if (status == 200) {
				System.out.println("把用户从房间移除成功,userName=" + userName + ",member=" + userType);
			}
			return status == 200;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * 锁住用户
	 * 
	 * @param userId
	 * @return 201成功,404用户不存在
	 */
	public static boolean lockUser(String userName) {
		try {
			String lockURL = "http://%s:9090/plugins/restapi/v1/lockouts/%s";

			lockURL = String.format(lockURL, host, userName);

			int status = httpGoReturnStatus(lockURL, "POST", null);
			if (status == 201) {
				System.out.println("锁定用户成功!userName=" + userName);
			} else if (status == 404) {
				System.out.println("用户不存在!userName=" + userName);
			}
			return status == 201;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * 解锁用户
	 * 
	 * @param userId
	 * @return 200成功,404用户不存在
	 */
	public static boolean unLockUser(String userName) {
		try {
			String unLockURL = "http://%s:9090/plugins/restapi/v1/lockouts/%s";
			unLockURL = String.format(unLockURL, host, userName);

			int status = httpGoReturnStatus(unLockURL, "DELETE", null);
			if (status == 200) {
				System.out.println("解锁定用户成功!userName=" + userName);
			} else if (status == 404) {
				System.out.println("用户不存在!userName=" + userName);
			}
			return status == 200;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * 删除用户
	 * 
	 * @param userName
	 * @return
	 */
	public static boolean deleteUser(String userName) {
		try {
			String deleteURL = "http://%s:9090/plugins/restapi/v1/users/%s";

			deleteURL = String.format(deleteURL, host, userName);

			int code = httpGoReturnStatus(deleteURL, "DELETE", null);

			if (code == 200) {
				System.out.println("用户删除成功!userName=" + userName);
			} else if (code == 404) {
				System.out.println("用户不存在!userName=" + userName);
			}
			return code == 200;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * 创建用户
	 * 
	 * @param userName
	 * @param password
	 * @return
	 */
	public static boolean createUser(String userName, String password) {
		try {
			String createURL = "http://%s:9090/plugins/restapi/v1/users";

			createURL = String.format(createURL, host);

			JSONObject obj = new JSONObject();
			obj.put("username", userName);
			obj.put("password", password);

			int code = httpGoReturnStatus(createURL, "POST", obj.toString());

			if (code == 201) {
				System.out.println("用户创建成功!userName=" + userName);
			} else if (code == 409) {
				System.out.println("用户已存在!userName=" + userName);
			}
			return code == 201;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * 
	 * 
	 * @param oldUserName
	 * @param userName
	 * @param password
	 * @return 200OK
	 */
	public static boolean updateUser(String oldUserName, String userName, String password) {
		try {
			String updateURL = "http://%s:9090/plugins/restapi/v1/users/%s";

			updateURL = String.format(updateURL, host, oldUserName);

			JSONObject obj = new JSONObject();
			if (!StringUtils.isBlank(userName)) {
				obj.put("username", userName);
			}
			if (!StringUtils.isBlank(password)) {
				obj.put("password", password);
			}
			int code = httpGoReturnStatus(updateURL, "PUT", obj.toString());

			if (code == 200) {
				System.out.println("用户修改成功!userName=" + oldUserName);
			} else {
				System.out.println("用户修改失败!userName=" + oldUserName);
			}
			return code == 200;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	public static boolean isExistUser(String userName) {
		try {
			String getURL = "http://%s:9090/plugins/restapi/v1/users/%s";

			getURL = String.format(getURL, host, userName);

			String user = httpGo(getURL, "GET", null);

			if (user == null) {
				System.out.println("用户不存在!userName=" + userName);
				return false;
			} else {
				System.out.println("用户已存在!userName=" + userName);
				return true;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	public static boolean isExistRoom(String roomName) {
		try {
			String getURL = "http://%s:9090/plugins/restapi/v1/chatrooms/%s";

			getURL = String.format(getURL, host, roomName);

			String room = httpGo(getURL, "GET", null);

			if (room == null) {
				System.out.println("房间不存在!room=" + roomName);
				return false;
			} else {
				System.out.println("房间已存在!room=" + roomName);
				return true;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * 创建房间
	 * 
	 * @param roomName
	 * @return 201成功
	 */
	public static boolean createChatRoom(String roomName) {
		try {
			String getURL = "http://%s:9090/plugins/restapi/v1/chatrooms";

			getURL = String.format(getURL, host);
			JSONObject obj = new JSONObject();

			obj.put("roomName", roomName);
			obj.put("naturalName", roomName);
			obj.put("description", roomName);
			obj.put("subject", roomName);
			obj.put("maxUsers", "0");
			obj.put("password", "");
			obj.put("persistent", "true");
			obj.put("publicRoom", "true");
			obj.put("registrationEnabled", "false");
			obj.put("canAnyoneDiscoverJID", "true");
			obj.put("canOccupantsChangeSubject", "false");
			obj.put("canOccupantsInvite", "false");
			obj.put("canChangeNickname", "false");
			obj.put("logEnabled", "false");
			obj.put("loginRestrictedToNickname", "true");
			obj.put("membersOnly", "false");
			obj.put("moderated", "false");

			List<String> list = new ArrayList<String>();
			list.add("moderator");
			list.add("participant");
			list.add("visitor");
			Map<String, List<String>> broadcastPresenceRole = new HashMap<String, List<String>>();

			broadcastPresenceRole.put("broadcastPresenceRole", list);

			obj.put("broadcastPresenceRoles", broadcastPresenceRole);

			Map<String, String> ower = new HashMap<String, String>();
			ower.put("owner", roomName + "@" + seriviceName);
			obj.put("owners", ower);

			// Map<String, String> admin = new HashMap<String, String>();
			// admin.put("admin", "chaoguan@" + seriviceName);
			// obj.put("admins", admin);

			int status = httpGoReturnStatus(getURL, "POST", obj.toString());
			System.out.println("创建房间成功!");
			return status == 201;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * 删除房间
	 * 
	 * @param roomName
	 * @return 200成功
	 */
	public static boolean deleteChatRoom(String roomName) {
		try {
			String getURL = "http://%s:9090/plugins/restapi/v1/chatrooms/%s";

			getURL = String.format(getURL, host, roomName);

			int status = httpGoReturnStatus(getURL, "DELETE", null);
			if (status == 200) {
				System.out.println("删除房间成功!");
			} else if (status == 404) {
				System.out.println("房间不存在!");
			}

			return status == 200;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * 修改房间属性
	 * 
	 * @param roomName
	 * @param maxUserCount
	 * @return 200OK
	 */
	public static boolean resetChatRoom(String roomName) {
		try {
			String getURL = "http://%s:9090/plugins/restapi/v1/chatrooms/%s";

			getURL = String.format(getURL, host, roomName);

			JSONObject obj = new JSONObject();
			obj.put("roomName", roomName);
			obj.put("naturalName", roomName);
			obj.put("description", roomName);
			obj.put("subject", roomName);
			obj.put("maxUsers", "0");
			obj.put("password", "");
			obj.put("persistent", "true");
			obj.put("publicRoom", "true");
			obj.put("registrationEnabled", "false");
			obj.put("canAnyoneDiscoverJID", "true");
			obj.put("canOccupantsChangeSubject", "false");
			obj.put("canOccupantsInvite", "false");
			obj.put("canChangeNickname", "false");
			obj.put("logEnabled", "false");
			obj.put("loginRestrictedToNickname", "true");
			obj.put("membersOnly", "false");
			obj.put("moderated", "false");

			List<String> list = new ArrayList<String>();
			list.add("moderator");
			list.add("participant");
			list.add("visitor");
			Map<String, List<String>> broadcastPresenceRole = new HashMap<String, List<String>>();

			broadcastPresenceRole.put("broadcastPresenceRole", list);

			obj.put("broadcastPresenceRoles", broadcastPresenceRole);

			Map<String, String> ower = new HashMap<String, String>();
			ower.put("owner", roomName + "@" + seriviceName);
			obj.put("owners", ower);

			// Map<String, String> admin = new HashMap<String, String>();
			// admin.put("admin", "chaoguan@" + seriviceName);
			// obj.put("admins", admin);

			int status = httpGoReturnStatus(getURL, "PUT", obj.toString());
			System.out.println("重置房间属性成功!");
			return status == 200;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * 修改所有的房间属性
	 * 
	 * @return
	 */
	public static boolean resetAllChatRoom() {

		try {
			String getURL = "http://%s:9090/plugins/restapi/v1/chatrooms?type=all ";

			getURL = String.format(getURL, host);

			String result = httpGo(getURL, "GET", null);

			if (StringUtils.isBlank(result)) {
				return true;
			}
			JSONObject obj = JSONObject.parseObject(result);

			JSONArray array = obj.getJSONArray("chatRoom");

			System.out.println("房间总个数=" + array.size());

			for (int i = 0; i < array.size(); i++) {
				JSONObject v = array.getJSONObject(i);

				String roomName = v.getString("roomName");

				System.out.println("正在修改的roomName=" + roomName);

				resetChatRoom(roomName);
			}
			System.out.println("重置所有房间属性成功!");
			return true;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * http返回状态
	 * 
	 * @param goURL
	 * @param method
	 * @param body
	 * @return
	 */
	private static int httpGoReturnStatus(String goURL, String method, String body) {
		HttpURLConnection urlConnection = null;
		try {
			urlConnection = (HttpURLConnection) new URL(goURL).openConnection();
			urlConnection.setRequestMethod(method);
			urlConnection.setDoOutput(true);
			urlConnection.setDoInput(true);
			urlConnection.setUseCaches(false);
			urlConnection.setConnectTimeout(6000);
			urlConnection.setReadTimeout(6000);
			// 正式
			urlConnection.setRequestProperty("Authorization", secret);
			urlConnection.setRequestProperty("Content-Type", "application/json");
			if (body != null) {
				urlConnection.getOutputStream().write(body.getBytes());
				urlConnection.getOutputStream().flush();
				urlConnection.getOutputStream().close();
			}
			return urlConnection.getResponseCode();

		} catch (Exception e) {
			return -1;
		} finally {
			urlConnection.disconnect();
		}
	}

	/**
	 * 返回数据，可以自定义返回格式
	 * 
	 * @param goURL
	 * @param method
	 * @param body
	 * @param accept
	 * @return
	 */
	private static String httpGo(String goURL, String method, String body) {
		HttpURLConnection urlConnection = null;
		try {
			urlConnection = (HttpURLConnection) new URL(goURL).openConnection();
			urlConnection.setRequestMethod(method);
			urlConnection.setDoOutput(true);
			urlConnection.setDoInput(true);
			urlConnection.setUseCaches(false);
			urlConnection.setConnectTimeout(3000);
			urlConnection.setReadTimeout(3000);
			// 正式
			urlConnection.setRequestProperty("Authorization", secret);
			urlConnection.setRequestProperty("Content-Type", "application/json");
			urlConnection.setRequestProperty("Accept", "application/json");

			if (body != null) {
				urlConnection.getOutputStream().write(body.getBytes());
				urlConnection.getOutputStream().flush();
				urlConnection.getOutputStream().close();
			}
			InputStream in = urlConnection.getInputStream();
			BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in));
			StringBuffer temp = new StringBuffer();
			String line;
			while ((line = bufferedReader.readLine()) != null) {
				temp.append(line);
			}
			bufferedReader.close();

			String ecod = urlConnection.getContentEncoding();
			if (ecod == null) {
				return temp.toString();
			} else {
				return new String(temp.toString().getBytes(), ecod);
			}

		} catch (Exception e) {
			return null;
		} finally {
			urlConnection.disconnect();
		}
	}

}
